// Copyright (c) 2023 Presto Labs Pte. Ltd.
// Author: tianqiang

#pragma once

#include "coin2/exchange/base/api_base/grpc/grpc_context.h"
#include "coin2/exchange/base/order/parser.h"
#include "coin2/service/web3/order_service.grpc.pb.h"

namespace coin2::exchange::uniswap::order_v3 {

class UniswapParser : public base::order::BaseParser {
 public:
  using GrpcContext = coin2::exchange::base::api_base::grpc::GrpcContext;
  using AccountBalanceResponse = ::coin2::service::QueryAccountBalanceResponseProto;
  using SubmitOrderResponse = ::coin2::service::QuerySubmitOrderResponseProto;
  using ProvideLiquidityResponse = ::coin2::service::QueryProvideLiquidityResponseProto;
  using WithdrawLiquidityResponse = ::coin2::service::QueryWithdrawLiquidityResponseProto;
  using NftTokenInfoResponse = ::coin2::service::QueryNftTokenInfoResponseProto;
  using NftTokenInfo = ::coin::proto::NftTokenInfo;
  using NftTokenInfoRequest = ::coin2::service::QueryNftTokenInfoRequestProto;

  const ParseResult& ParseRawMessage(const RawMessage& msg) override;

 private:
  void ParseAccountBalance(const std::shared_ptr<GrpcContext>& grpc_context);
  void ParseNftTokenInfo(const std::shared_ptr<GrpcContext>& grpc_context);

  AccountBalance ParseBalance(const std::shared_ptr<AccountBalanceResponse>& response);

  bool ParseRawBalance(
      const std::shared_ptr<AccountBalanceResponse>& response,
      RawBalanceMap* raw_balance_map);

  void ParseSubmitResponse(const std::shared_ptr<GrpcContext>& grpc_context);

  void ParseProvideLiquidity(const std::shared_ptr<GrpcContext>& grpc_context);
  void ParseWithdrawLiquidity(const std::shared_ptr<GrpcContext>& grpc_context);
};

}  // namespace coin2::exchange::uniswap::order_v3
